位图图像( bitmap image )又称栅格图( raster graphics ),由像素矩阵组成,也就是由无数个像素点组成 。位图图像的特点是色彩变化丰富,可逼真地再现世界,因此常用于数码照片、页面效果图等。但当无限放大时,将会看到像素块,图像会失真。
矢量图形( vector graphics )由点和线组成,把点看成是一个坐标,在两个点之间用曲线或直线连接,可以组成任何形状 。与位图相比,色彩比较简单,无法表现逼真图像,但是当放大、缩小或旋转的时候,不会丢失细节,也不会影响清晰度(即不失真),常用于三维建模、特殊字体、图标和 logo 等。
canvas 元素是 HTML 5 的新元素,用于在网页上绘制图形,相当于在 HTML 中嵌入了一张画布,这样就可以直接在页面上进行图形操作了,因此 canvas 具有极大的应用价值,可以在较多场景下使用。
默认情况下, Canvas 所创建的矩形区域大小为宽 300 像素、高 150 像素,也可以使用 width 与 height 属性来自定义其宽度和高度。
canvas 元素本身是没有绘图能力的,需要借助额外的 JavaScript 脚本来实现绘图。
canvas 元素只是一个容器,只使用它并不能够做任何事情。在 Windows 里绘制图形时需要先得到一个设备上下文 DC ,同样,在 canvas 元素上绘图时也需要得到一个渲染上下文对象 Context 。
上下文对象可以让各种不同的图形设备在外界看起来都是一个样式,这样读者只需要关注绘图,其它的工作都可以交给操作系统和浏览器。简单来说,上下文对象就是把各式各样的具体变成一个统一的抽象,从而减轻开发人员的负担。使用 canvas 绘图时并不是直接绘制到屏幕上的,而是先画到一个上下文 Context 上,然后再刷新到屏幕上。
一个 canvas 元素中只能有一个唯一的 ID 并且每个上下文对象也都是唯一的,获取渲染上下文对象 Context 非常简单,首先获取 canvas 元素对象,然后再调用 canvas 对象的 getContext() 方法。
SVG ( Scalable Vector Graphics )即可伸缩矢量图形,是一种用 XML 描述图形的标记语言,用于描述二维矢量图形的一种图形格式。 SVG 由 W3C 制定,是一个开放标准。另外, SVG 还是 Static Var Generator (静止无功发生器)的简称。,早在 2003 年就已成为 W3C 标准。与 Canvas 只能用 JavaScript 绘图不同, SVG 提供了各种类型的元素,包括形状、文本、渐变、动画和滤镜等,并且可以为每个元素附加 DOM 事件,还能用 CSS 控制它们的样式,不过只能使用部分 CSS 属性,如 border 、 background 就不可用。 SVG 中也可插入图像(即插入 img 元素),执行裁剪、遮罩、旋转等功能。不过, SVG 不能像 canvas 那样,将处理过的图形输出, canvas 元素有个 toDataURL ()方法,可以将画布中的内容编码成字符串形式。
SVG 有很多优势,例如,其图像可以通过文本编辑器来创建和更改, SVG 图像可以被搜索、索引、脚本化或压缩, SVG 图像可以在任何的分辨率下被高质量地打印,以及可以在图像质量不下降的情况下被放大等。
Canvas | SVG | |
---|---|---|
依赖分辨率 | 依赖分辨率 | 不依赖分辨率 |
事件处理器 | 不支持事件处理器 | 支持事件处理器 |
渲染能力 | 比较弱, 不适合大型程序 | 最适合带有大型渲染区域的应用程序, 如谷歌地图 |
游戏应用 | 最适合图像密集型的游戏 | 不太适合做游戏应用 |
有些浏览器可能不支持 canvas 元素,因此就需要为这些浏览器提供替代显示的内容。方法比较简单,只需要直接在 canvas 元素内插入替代内容即可。不支持 canvas 的浏览器会忽略 canvas 元素而直接显示替代内容,支持 Canvas 的浏览器则会正常地渲染 Canvas 。
可以使用 JavaScript 脚本来检测浏览器是否支持 canvas ,方法是判断 getContext 函数是否存在。
为了减少对单一画布的操作、 提高画布性能, 在较为复杂场景下, 可以使用多层画布 。
目前, 制作动画可以使用 CSS 3 的 animattion + keyframes , 也可以使用 CSS 3 的 transition 属性, 或者使用 SVG 。 当然还可以使用最原始的 window.setTimout() 或者 window.setInterval() 方法, 通过不断更新元素的状态位置等来实现动画, 前提是画面的更新频率要达到每秒 60 次才能让肉眼看到流畅的动画效果。
setTimeout() 几乎在所有浏览器上都运行得不错, 但还有一个更好的方法, 那就是 requestAnimFrame 。 requestAnimFrame 方法原理与 setTimeout / setInterval 差不多, 通过递归调用同一方法来不断更新画面以达到动起来的效果, 但它优于 setTimeout / setInterval , 在于它是由浏览器专门为动画提供的 API , 在运行时浏览器会自动优化方法的调用, 并且如果页面不是激活状态的话, 动画会自动暂停, 可以优化绘制循环, 减少与剩下的页面回流, 有效节省了 CPU 开销。
可以直接调用 requestAnimationFrame 方法, 也可以通过 window 来调用, 接收一个函数作为回调, 返回一个 ID 值, 通过把这个 ID 值传给 window.cancelAnimationFrame() 可以取消该次动画。
根据画布所包含的文件元素的大小来灵活地调整画布尺寸 。
圆形进度条的步骤是: 开始画一个灰色的圆、 填充颜色、 画进度、 画内部空白、 画一条线、 在画布中间写上进度文案 。
使用 clearRect 方法可清除指定的矩形区域内的所有图形, 显示出画布的背景 。
context.clearRect(x, y, width, height);